/**
 * 下拉框 下拉树 复选框 单选等控件的值来源处理
 *
 * valMode:single单值 double双值
 *
 */

import {FormApi} from "@/api/FormApi.js";
import Util from "@/js/Util.js";

export default {
    data() {
        return {
            options: [],
            flag:false,
            // 用于存储观察者的集合
            watchers:[]
        }
    },
    computed:{
        isDisabled(){//控件的禁用；（单选控件，复选控件，下拉选择器）
            return (item)=>{
                if(!item){
                    return false
                }
                let disabledCondition = item.disabledCondition ;
                if(disabledCondition && disabledCondition.trim()){
                    if(disabledCondition.indexOf('return') == -1){
                        disabledCondition = 'return ' + item.disabledCondition ;
                    }
                    let func = new Function('row',disabledCondition);
                    return func.call(this.formVm,this.data);
                }
                return false ;
            }
        }
    },
    methods:{
        /**
         * 初始化数据来源
         * @param (Function) callback 回调方法
         */
        async initDataSource(callback) {
            let json=this.metadata.options.sourceConfig;
            let valueSource=this.metadata.options.valueSource;
            if(this.flag){
                return;
            }
            let self=this;
            await this.loadDataSource(json,valueSource,function (cacheKey){
                let options=Util.deepClone(self.options);
                if(self.formVm.fieldSourceCache[cacheKey]){
                    self.formVm.fieldSourceCache[cacheKey].options.length=0;
                    self.formVm.fieldSourceCache[cacheKey].options.push(...options)
                }
                if(callback){
                    callback();
                }
            })
        },
        /**
         * 加载数据源
         * @param (Object) json 数据源配置
         * @param (String) valueSource 来源于
         * @param (Function) callback 回调方法
         * @returns {Promise<void>}
         */
        async loadDataSource(json,valueSource,callback){
            if(valueSource=='custom'){
                this.options = json.options;
                if(callback) {
                    callback();
                }
            }else if(valueSource=='dic'){
                await this.loadByDic(json,callback);
            }else if(valueSource=='sql'){
                await this.loadBySql(json,callback);
            }else if(valueSource=='interface'){
                await this.loadByInterface(json,callback);
            }else if(valueSource=='grant'){
                await this.loadByGrant(json,callback);
            }else if(valueSource=='script'){
                await this.getScriptData(json,callback);
            }
        },
        async loadByDic(json,callback) {
            let dicKey = json.dicKey;
            if (dicKey == "" || dicKey == undefined) {
                return;
            }
            let self_ = this;
            let cacheKey='dic_'+dicKey+"_default";
            let fieldSourceCache = {} ;
            if(self_.formVm && self_.formVm.fieldSourceCache){
                fieldSourceCache = self_.formVm.fieldSourceCache[cacheKey];
            }
            if(fieldSourceCache && fieldSourceCache.load){
                self_.options=self_.formVm.fieldSourceCache[cacheKey].options;
                if(callback) {
                    callback(cacheKey);
                }
                return;
            }
            if(self_.formVm && self_.formVm.fieldSourceCache){
                self_.formVm.fieldSourceCache[cacheKey]={
                    options:[],
                    load:true,
                }
            }
            //数据字典
            let data =  await FormApi.getDicByAlias(dicKey,"");
            self_.flag = true;
            if (data) {
                let _options = data.map(item => {
                    return {label: item.name.trim(), value: item.value.trim(), disabled: false};
                });
                self_.options = _options;
                if (callback) {
                    callback(cacheKey);
                }
            }

        },
        getOptions(){//过滤数据；单选控件，复选控件，下拉选择器;
            let self = this ;
            if(!this.options){
                return [];
            }
            let _options = this.options.map(item=>{
                let label = item.label;
                let disabled = this.isDisabled(item);
                return {
                    ...item,
                    label:label.hasOwnProperty(self.language)?label[self.language]:label,
                    disabled:disabled || false
                }
            });
            //如果有设置过滤方法
            let _filterSelect = this.metadata.options.filterOptions
            if(_filterSelect){
                _options = this.formVm[_filterSelect](_options);
            }
            return _options;
        },
        //自定义sql
        async loadBySql(json,callback){
            let sqlkey=json.sqlKey;
            if(sqlkey =="" || sqlkey ==undefined){
                return;
            }
            //自定义sql
            let textField=json.textField;
            let valueField=json.valueField;
            let params=json.params;
            if((!sqlkey || !textField || !valueField)
                && this.metadata.type!="autoComplete"
                && (this.metadata.type=="autoComplete" && !json.formatValue)) {
                return;
            }
            let self_ = this;
            let paramsStr=JSON.stringify(this.getParamsInput(params));
            let cacheKey='sql_'+sqlkey+paramsStr;
            let fieldSourceCache=self_.formVm.fieldSourceCache[cacheKey];
            if(fieldSourceCache && fieldSourceCache.load){
                self_.options=fieldSourceCache.options;
                if(callback) {
                    callback(cacheKey);
                }
                return;
            }
            self_.formVm.fieldSourceCache[cacheKey]={
                options:[],
                load:true,
            }
            let res = await FormApi.queryForJson(sqlkey,{params:paramsStr})
            self_.flag=true;
            if(this.metadata.type!="autoComplete"){
                let _options = res.data.map(item=>{
                    return {label:item[textField].trim(),value:item[valueField].trim(),disabled:false,...item};
                })
                self_.options= _options ;
            }else {
                self_.options=res.data;
            }
            if(callback){
                callback(cacheKey);
            }
        },
        getParamsInput(parameters){
            if(!parameters||parameters.length==0) {
                return {};
            }
            let params={};
            for(let i=0,j=parameters.length;i<j;i++){
                let obj=parameters[i];
                if(!obj.val) continue;
                //[{name: "PARENT_CODE_",table: "curForm",type: "mapping",val: "city",valMode: "single",mode:"mapping"}]
                //模式为脚本
                if(obj.mode=="script"){
                    if(obj.val){
                        let returnVal=this.formVm[obj.val]();
                        if(!returnVal) {
                            delete params[obj.name];
                        }else {
                            params[obj.name]=returnVal;
                        }
                    }
                }else {
                    let val="";
                    if (obj.table != "curForm") {
                        val = this.data[obj.val]
                    } else {
                        val = this.formVm.data[obj.val]
                    }
                    //父联动字段为空
                    if(!val) {
                        delete params[obj.name];
                    } else {
                        if(!obj.valMode || obj.valMode=="single"){
                            params[obj.name]=val;
                        }
                        else{
                            let json=JSON.parse(val);
                            params[obj.name]=json.value;
                        }
                    }
                    let self=this;
                    var prefix=obj.table=="curForm"? "formVm.data.":"data.";
                    let key=prefix + obj.val;
                    //已添加过就不用监听了
                    if(self.watchers.includes(key)){
                        return params;
                    }
                    self.watchers.push(key);
                    //值变化时 需重新加载选项
                    this.$watch(key,function(val, oldVal) {
                        self.flag=false;
                        //树控件
                        if(self.metadata.type=="treeSelect"){
                            this.initTreeDataSource();
                        }else {
                            self.initDataSource()
                        }
                    });
                }
            }
            return params;
        },
        //第三方接口
        async loadByInterface(json,callback){
            let interFaceKey=json.interFaceKey;
            if(interFaceKey=="" || interFaceKey==undefined){
                return;
            }
            let interFaceTextField=json.interFaceTextField;
            let interFaceValueField=json.interFaceValueField;
            let isobject=json.isobject;
            let params=json.params;
            if((!interFaceKey || !interFaceTextField || !interFaceValueField  )
                && this.metadata.type!="autoComplete"
                && (this.metadata.type=="autoComplete" && !json.formatValue)){
                return;
            }
            let self_ = this;
            let paramsObj={};
            if(params && Object.keys(params).length>0 ) {
                for(let key in params){
                    let paramsInput = this.getInterfaceParamsInput(params[key]);
                    paramsObj[key]=JSON.stringify(paramsInput);
                }
            }
            let cacheKey='interface_'+interFaceKey+JSON.stringify(paramsObj);
            let fieldSourceCache = self_.formVm.fieldSourceCache[cacheKey];
            if(fieldSourceCache && fieldSourceCache.load){
                self_.options = fieldSourceCache.options;
                if(callback) {
                    callback(cacheKey);
                }
                return;
            }
            self_.formVm.fieldSourceCache[cacheKey]={
                options:[],
                load:true,
            }
            let res = await FormApi.executeInterfaceApi(interFaceKey,paramsObj);
            self_.flag=true;
            let _options = "" ;
            if (res.success) {
                if(this.metadata.type!="autoComplete"){
                    if (isobject) {
                        _options = res.data.map(item=>{
                            return {label:item[interFaceTextField],value:item[interFaceValueField],disabled:false};
                        })
                        self_.options = _options ;
                    } else {
                        let ary = [];
                        if (res.data) {
                            for (let i = 0; i < res.data.length; i++) {
                                ary.push({label: res.data[i], value: res.data[i]});
                            }
                        }
                        _options = ary ;
                        self_.options = ary;
                    }
                }else {
                    self_.options =  res.data;
                    _options= self_.options  ;
                }
            }else {
                self_.formVm.fieldSourceCache[cacheKey].load=false;
            }
            if(callback){
                callback(cacheKey);
            }
        },
        getInterfaceParamsInput(parameters){
            if(!parameters||parameters.length==0) {
                return {};
            }
            let params={};
            for(let i=0,j=parameters.length;i<j;i++){
                let obj=parameters[i];
                if(obj.paramType=='object'){
                    params[obj.name]=this.getInterfaceParamsInput(obj.children);
                }else if(obj.paramType=='array'){
                    params[obj.name]=[this.getInterfaceParamsInput(obj.children)];
                }else{
                    //[{name: "PARENT_CODE_",table: "curForm",paramType:"",type: "mapping",val: "city",valmode: "single"}]
                    let val="";
                    if (obj.table != "curForm") {
                        val = this.data[obj.val]
                    } else {
                        val = this.formVm.data[obj.val]
                    }
                    //父联动字段为空
                    if(!val) {
                        delete params[obj.name];
                    } else {
                        if(val.indexOf("{")==-1){
                            params[obj.name]=val;
                        }
                        else{
                            let json=JSON.parse(val);
                            params[obj.name]=json.value;
                        }
                    }
                    let self=this;
                    var prefix=obj.table=="curForm"? "formVm.data.":"data.";
                    let key=prefix + obj.val;
                    //已添加过就不用监听了
                    if(self.watchers.includes(key)){
                        return params;
                    }
                    //值变化时 需重新加载选项
                    this.$watch(key,function(val, oldVal) {
                        self.flag=false;
                        self.watchers.push(key);
                        //树控件
                        if(self.metadata.type=="treeSelect"){
                            this.initTreeDataSource();
                        }else {
                            self.initDataSource()
                        }
                    });
                }
            }
            return params;
        },
        //数据权限
        async loadByGrant(json,callback){
            let grantKey=json.grantKey;
            if(grantKey=="" || grantKey==undefined){
                return;
            }
            let self_=this;
            let cacheKey='grant_' + grantKey+"_default";
            let fieldSourceCache=self_.formVm.fieldSourceCache[cacheKey];
            if(fieldSourceCache && fieldSourceCache.load){
                self_.options=fieldSourceCache.options;
                if(callback) {
                    callback(cacheKey);
                }
                return;
            }
            self_.formVm.fieldSourceCache[cacheKey]={
                options:[],
                load:true,
            }
            FormApi.loadByGrant(grantKey).then(res=>{
                self_.flag = true;
                let _options = [];
                if(res.data && res.data.length>0){
                    _options = res.data.map(item=>{
                        return {label:item['label'],value:item['value'],disabled:false};
                    })
                }
                self_.options = _options ;
                if(callback){
                    callback(cacheKey);
                }
            })
        },
        //脚本数据
        async getScriptData(json,callback) {
            let options=[];
            if(json.scriptMethod && this.formVm[json.scriptMethod]){
                options = this.formVm[json.scriptMethod]();
            }
            this.options=options;
            if(callback){
                callback();
            }
        },
        /**
         * 处理自定义查询关联字段
         * @param value
         * 单选 直接返回值
         * 多选 返回数组值
         */
        handFieldMapping(value){
            let json=this.metadata.options.sourceConfig;
            let fieldMapping=json.fieldMapping;
            if(!fieldMapping || fieldMapping.length==0){
                return;
            }
            //多选
            if(value && Array.isArray(value)){
                for (let i = 0; i < fieldMapping.length; i++) {
                    let mapping=fieldMapping[i];
                    let bindField=mapping["bindField"];
                    let returnValue=mapping["returnValue"];
                    let val="";
                    for (let i = 0; i < value.length; i++) {
                        let _option= this.initOptions(this.options,value[i])
                        if(_option){
                            if(mapping.valMode=='double'){//多值
                                let returnLabel=mapping["returnLabel"];
                                let obj;
                                if(val){
                                    obj=JSON.parse(val);
                                    obj.label+=","+_option[returnLabel]
                                    obj.value+=","+_option[returnValue]
                                }else {
                                    obj={
                                        label:_option[returnLabel],
                                        value:_option[returnValue]
                                    }
                                }
                                val=JSON.stringify(obj);
                            }else { //单值
                                val=val?val+","+_option[returnValue]:_option[returnValue];
                            }
                        }
                    }
                    this.curData[bindField]=val;
                }
            }else {//单选
                let _option= this.initOptions(this.options,value)
                for (let i = 0; i < fieldMapping.length; i++) {
                    let mapping=fieldMapping[i];
                    let bindField=mapping["bindField"];
                    let returnValue=mapping["returnValue"];
                    let val="";
                    if(_option){
                        if(mapping.valMode=='double'){//多值
                            let returnLabel=mapping["returnLabel"];
                            let obj={
                                label:_option[returnLabel],
                                value:_option[returnValue]
                            }
                            val=JSON.stringify(obj);
                        }else {//单值
                            val=_option[returnValue];
                        }
                    }
                    this.curData[bindField]=val;
                }
            }
        },
        initOptions(list,val){
            let name = ''
            for (const res of list) {
                if(res.value == val){
                    return res
                    break;
                }else if(res.children){
                    name = this.initOptions(res.children,val);
                    if(name){
                        return name
                        break;
                    }
                }
            }
        },
        /**
         * 触发初始化事件
         */
        executeInitCustomQuery(value){
            let event = "";
            //判断当前触发的事件
            if (this.readOnly) {
                event = "detailInit";
            } else {
                if (this.data.ID_) {
                    event = "editInit";
                } else {
                    event = "addInit";
                }
            }
            this.triggerEmitEvents(event,value,this.data)
        }
    }
}
